"""
考试系统 - API序列化器
"""
from rest_framework import serializers
from django.contrib.auth import get_user_model
from django.core.exceptions import ValidationError
from django.utils import timezone

from .models import (
    Examination, ExaminationQuestion, ExaminationSession,
    ExaminationAnswer, ExaminationTemplate, ExamStatistics
)
from apps.question_bank.models import Question, QuestionBank

User = get_user_model()


class ExaminationQuestionSerializer(serializers.ModelSerializer):
    """考试题目序列化器"""
    question_title = serializers.CharField(source='question.title', read_only=True)
    question_type = serializers.CharField(source='question.type', read_only=True)
    question_content = serializers.CharField(source='question.stem', read_only=True)
    question_options = serializers.JSONField(source='question.options', read_only=True)
    effective_score = serializers.DecimalField(max_digits=5, decimal_places=2, read_only=True)

    class Meta:
        model = ExaminationQuestion
        fields = [
            'id', 'question', 'question_title', 'question_type', 'question_content',
            'question_options', 'question_order', 'custom_score', 'effective_score', 'is_required'
        ]


class ExaminationSerializer(serializers.ModelSerializer):
    """考试序列化器"""
    creator_info = serializers.SerializerMethodField()
    question_count = serializers.SerializerMethodField()
    status_display = serializers.CharField(source='get_status_display', read_only=True)
    exam_type_display = serializers.CharField(source='get_exam_type_display', read_only=True)

    class Meta:
        model = Examination
        fields = [
            'id', 'title', 'description', 'exam_type', 'exam_type_display', 'status', 'status_display',
            'start_time', 'end_time', 'duration', 'creator', 'creator_info', 'question_bank',
            'question_count', 'total_score', 'pass_score', 'allow_late_join', 'auto_submit',
            'show_score', 'show_answer', 'allow_retake', 'question_mode', 'created_at', 'updated_at'
        ]
        read_only_fields = ['creator']

    def get_creator_info(self, obj):
        """获取创建者信息"""
        return {
            'id': obj.creator.id,
            'username': obj.creator.username,
            'real_name': obj.creator.real_name
        }

    def get_question_count(self, obj):
        """获取题目数量"""
        return obj.questions.count()


class ExaminationDetailSerializer(ExaminationSerializer):
    """考试详情序列化器"""
    questions = ExaminationQuestionSerializer(source='questions.all', many=True, read_only=True)
    supervisors_info = serializers.SerializerMethodField()

    class Meta(ExaminationSerializer.Meta):
        fields = ExaminationSerializer.Meta.fields + [
            'questions', 'supervisors', 'supervisors_info'
        ]

    def get_supervisors_info(self, obj):
        """获取监考人员信息"""
        return [
            {
                'id': supervisor.id,
                'username': supervisor.username,
                'real_name': supervisor.real_name
            }
            for supervisor in obj.supervisors.all()
        ]


class ExaminationCreateSerializer(serializers.ModelSerializer):
    """考试创建序列化器"""
    question_ids = serializers.ListField(
        child=serializers.CharField(),
        write_only=True,
        required=False
    )

    class Meta:
        model = Examination
        fields = [
            'title', 'description', 'exam_type', 'start_time', 'end_time', 'duration',
            'question_bank', 'total_score', 'pass_score', 'allow_late_join', 'auto_submit',
            'show_score', 'show_answer', 'allow_retake', 'question_mode', 'question_ids',
            'supervisors'
        ]

    def validate(self, data):
        """验证数据"""
        # 验证时间
        if data.get('start_time') and data.get('end_time'):
            if data['start_time'] >= data['end_time']:
                raise ValidationError("结束时间必须大于开始时间")

        # 验证时长
        if data.get('duration') and data.get('start_time') and data.get('end_time'):
            expected_duration = (data['end_time'] - data['start_time']).total_seconds() / 60
            if data['duration'] > expected_duration:
                raise ValidationError("考试时长不能大于考试时间范围")

        # 验证分数
        pass_score = data.get('pass_score', 0)
        total_score = data.get('total_score', 0)
        if pass_score > total_score:
            raise ValidationError("及格分数不能大于总分")

        return data

    def create(self, validated_data):
        """创建考试"""
        question_ids = validated_data.pop('question_ids', [])
        supervisors = validated_data.pop('supervisors', [])

        # 创建考试
        examination = Examination.objects.create(**validated_data)

        # 添加题目
        if question_ids:
            questions = Question.objects.filter(id__in=question_ids)
            for i, question in enumerate(questions, 1):
                ExaminationQuestion.objects.create(
                    examination=examination,
                    question=question,
                    question_order=i
                )

        # 添加监考人员
        if supervisors:
            examination.supervisors.set(supervisors)

        return examination


class ExaminationListSerializer(serializers.ModelSerializer):
    """考试列表序列化器"""
    creator_name = serializers.CharField(source='creator.real_name', read_only=True)
    question_bank_name = serializers.CharField(source='question_bank.name', read_only=True)
    status_display = serializers.CharField(source='get_status_display', read_only=True)
    exam_type_display = serializers.CharField(source='get_exam_type_display', read_only=True)
    participant_count = serializers.SerializerMethodField()

    class Meta:
        model = Examination
        fields = [
            'id', 'title', 'exam_type', 'exam_type_display', 'status', 'status_display',
            'start_time', 'end_time', 'duration', 'creator_name', 'question_bank_name',
            'total_score', 'pass_score', 'participant_count', 'created_at'
        ]

    def get_participant_count(self, obj):
        """获取参与人数"""
        return obj.exam_sessions.count()


class ExaminationSessionSerializer(serializers.ModelSerializer):
    """考试会话序列化器"""
    user_info = serializers.SerializerMethodField()
    examination_title = serializers.CharField(source='examination.title', read_only=True)
    status_display = serializers.CharField(source='get_status_display', read_only=True)

    class Meta:
        model = ExaminationSession
        fields = [
            'id', 'examination', 'examination_title', 'user', 'user_info',
            'status', 'status_display', 'started_at', 'finished_at', 'time_spent',
            'total_score', 'objective_score', 'subjective_score', 'passed',
            'ip_address', 'cheating_detected', 'created_at'
        ]
        read_only_fields = ['user', 'total_score', 'objective_score', 'subjective_score', 'passed']

    def get_user_info(self, obj):
        """获取用户信息"""
        return {
            'id': obj.user.id,
            'username': obj.user.username,
            'real_name': obj.user.real_name
        }


class ExaminationSessionDetailSerializer(ExaminationSessionSerializer):
    """考试会话详情序列化器"""
    answers = serializers.SerializerMethodField()
    remaining_time = serializers.SerializerMethodField()

    class Meta(ExaminationSessionSerializer.Meta):
        fields = ExaminationSessionSerializer.Meta.fields + ['answers', 'remaining_time']

    def get_answers(self, obj):
        """获取答案"""
        answers = obj.exam_answers.all()
        return [
            {
                'id': answer.id,
                'question_id': answer.exam_question.question.id,
                'question_title': answer.exam_question.question.title,
                'question_type': answer.exam_question.question.type,
                'answer': answer.answer,
                'text_answer': answer.text_answer,
                'score': float(answer.score) if answer.score else None,
                'is_correct': answer.is_correct,
                'status': answer.status,
                'answered_at': answer.answered_at,
                'time_spent': answer.time_spent
            }
            for answer in answers
        ]

    def get_remaining_time(self, obj):
        """获取剩余时间"""
        if obj.status != ExaminationSession.SessionStatus.IN_PROGRESS:
            return 0
        return obj.remaining_time


class ExaminationAnswerSerializer(serializers.ModelSerializer):
    """考试答案序列化器"""
    question_title = serializers.CharField(source='exam_question.question.title', read_only=True)
    question_type = serializers.CharField(source='exam_question.question.type', read_only=True)
    max_score = serializers.DecimalField(
        source='exam_question.effective_score',
        read_only=True,
        max_digits=6,
        decimal_places=2
    )

    class Meta:
        model = ExaminationAnswer
        fields = [
            'id', 'exam_session', 'exam_question', 'question_title', 'question_type',
            'answer', 'text_answer', 'score', 'is_correct', 'status', 'max_score',
            'answered_at', 'time_spent', 'first_view_at', 'view_count'
        ]


class ExaminationAnswerCreateSerializer(serializers.ModelSerializer):
    """考试答案创建序列化器"""

    class Meta:
        model = ExaminationAnswer
        fields = [
            'exam_session', 'exam_question', 'answer', 'text_answer',
            'answered_at', 'time_spent'
        ]

    def validate(self, data):
        """验证数据"""
        exam_session = data['exam_session']
        exam_question = data['exam_question']

        # 验证会话状态
        if exam_session.status != ExaminationSession.SessionStatus.IN_PROGRESS:
            raise ValidationError("只能在进行中的考试提交答案")

        # 验证题目归属
        if exam_question.examination != exam_session.examination:
            raise ValidationError("题目不属于此考试")

        # 验证用户权限
        # 这里假设当前用户就是会话用户，实际使用时需要从请求中获取

        return data


class SessionAnswerDetailSerializer(ExaminationAnswerSerializer):
    """会话答案详情序列化器"""
    question_content = serializers.CharField(source='exam_question.question.stem', read_only=True)
    question_options = serializers.JSONField(source='exam_question.question.options', read_only=True)
    correct_answer = serializers.CharField(source='exam_question.question.answer', read_only=True)

    class Meta(ExaminationAnswerSerializer.Meta):
        fields = ExaminationAnswerSerializer.Meta.fields + [
            'question_content', 'question_options', 'correct_answer'
        ]


class ExaminationTemplateSerializer(serializers.ModelSerializer):
    """考试模板序列化器"""
    creator_info = serializers.SerializerMethodField()
    exam_type_display = serializers.CharField(source='get_exam_type_display', read_only=True)
    pass_score = serializers.SerializerMethodField()

    class Meta:
        model = ExaminationTemplate
        fields = [
            'id', 'name', 'description', 'exam_type', 'exam_type_display',
            'duration', 'question_mode', 'question_config', 'total_score',
            'pass_percentage', 'pass_score', 'settings', 'usage_count',
            'creator', 'creator_info', 'created_at', 'updated_at'
        ]
        read_only_fields = ['creator', 'usage_count']

    def get_creator_info(self, obj):
        """获取创建者信息"""
        return {
            'id': obj.creator.id,
            'username': obj.creator.username,
            'real_name': obj.creator.real_name
        }

    def get_pass_score(self, obj):
        """获取及格分数"""
        return obj.get_pass_score()


class ExamStatisticsSerializer(serializers.ModelSerializer):
    """考试统计序列化器"""
    pass_rate = serializers.SerializerMethodField()
    average_score_percentage = serializers.SerializerMethodField()

    class Meta:
        model = ExamStatistics
        fields = [
            'id', 'examination', 'total_participants', 'completed_count', 'passed_count',
            'pass_rate', 'average_score', 'highest_score', 'lowest_score',
            'average_score_percentage', 'score_distribution', 'question_analysis',
            'time_analysis', 'updated_at'
        ]

    def get_pass_rate(self, obj):
        """获取及格率"""
        if obj.total_participants > 0:
            return round(obj.passed_count / obj.total_participants * 100, 2)
        return 0

    def get_average_score_percentage(self, obj):
        """获取平均分百分比"""
        if obj.examination and obj.examination.total_score > 0:
            return round(float(obj.average_score) / float(obj.examination.total_score) * 100, 2) if obj.average_score else 0
        return 0


class QuestionBankSelectSerializer(serializers.ModelSerializer):
    """题库选择序列化器"""
    owner_name = serializers.CharField(source='owner.real_name', read_only=True)
    type_display = serializers.CharField(source='get_type_display', read_only=True)

    class Meta:
        model = QuestionBank
        fields = [
            'id', 'name', 'description', 'type', 'type_display', 'subject',
            'grade_level', 'question_count', 'total_points', 'owner', 'owner_name',
            'is_public', 'allow_export', 'created_at'
        ]
        read_only_fields = ['owner', 'question_count', 'total_points']